package kr.salebeans.cm.provider.sale.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import kr.salebeans.cm.domain.sale.Sale;
import kr.salebeans.cm.provider.sale.SaleProvider;
import kr.salebeans.cm.sale.search.InteSaleSearchCond;
import kr.salebeans.cm.sale.search.InteSaleSearchCond.InteSaleSearchType;

public class SaleProviderImpl implements SaleProvider {

    @PersistenceContext
    private EntityManager em;

    @Override
    public Sale createSale(Sale sale) {
        sale.createNewHandling();
        this.em.persist(sale);
        return sale;
    }

    @Override
    public Sale updateSale(Sale sale) {
        return this.em.merge(sale);
    }

    @Override
    public Sale retrieveSale(long saleId) {
        return this.em.find(Sale.class, saleId);
    }

    @Override
    public List<Map<Integer, Object>> retrieveInteSaleList(InteSaleSearchCond inteSaleSearchCond) {
        String subStringStr = null;
        if (inteSaleSearchCond.getInteSaleSearchType() == InteSaleSearchType.DAY) {
            subStringStr = " SUBSTRING(s.handling.updateDateTime, 0, 8) ";
        }
        else if (inteSaleSearchCond.getInteSaleSearchType() == InteSaleSearchType.MONTH) {
            subStringStr = " SUBSTRING(s.handling.updateDateTime, 0, 6) ";
        }
        else if (inteSaleSearchCond.getInteSaleSearchType() == InteSaleSearchType.YEAR) {
            subStringStr = " SUBSTRING(s.handling.updateDateTime, 0, 4) ";
        }
        StringBuilder qlString = new StringBuilder();
        qlString.append(" SELECT ").append(subStringStr).append(", COUNT(s), SUM(s.saleAmount) ");
        qlString.append(" FROM Sale s ");
        qlString.append(" WHERE s.shopId = :shopId ");

        qlString.append(" AND ").append(subStringStr).append(" BETWEEN :from AND :end ");
        qlString.append(" GROUP BY ").append(subStringStr);
        qlString.append(" ORDER BY ").append(subStringStr).append(" DESC ");

        Query query = this.em.createQuery(qlString.toString());
        query.setParameter("shopId", inteSaleSearchCond.getShopId());
        query.setParameter("from", inteSaleSearchCond.getSearchFromDate());
        query.setParameter("end", inteSaleSearchCond.getSearchEndDate());

        List<Object[]> queryResults = (List<Object[]>) query.getResultList();
        if (queryResults == null) return null;
        List<Map<Integer, Object>> resultMap = new ArrayList<Map<Integer,Object>>();
        for (Object[] objects : queryResults) {
            Map<Integer, Object> map = new HashMap<Integer, Object>();
            map.put(InteSaleSearchCond.DAY_FIELD, (String) objects[0]);
            map.put(InteSaleSearchCond.CUSTOMER_COUNT_FIELD, (Long) objects[1]);
            map.put(InteSaleSearchCond.AMOUNT_FIELD, (Long) objects[2]);
            resultMap.add(map);
        }
        return resultMap;
    }
}
